package com.niiwoo.civet.account.service.dubbo;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.dao.entity.AccountBase;
import com.niiwoo.civet.account.dao.entity.ProjectInvestCustodyOrder;
import com.niiwoo.civet.account.dto.common.ProjectInvestCancelOrderDTO;
import com.niiwoo.civet.account.dto.common.ProjectInvestCustodyOrderDTO;
import com.niiwoo.civet.account.dto.request.InvestPayDubboRequestDTO;
import com.niiwoo.civet.account.dto.response.CompleteInvestOrderResponseDTO;
import com.niiwoo.civet.account.dto.response.InvestPaymentRedoResponseDTO;
import com.niiwoo.civet.account.service.AccountInvestDubboService;
import com.niiwoo.civet.account.service.local.AccountInvestService;
import com.niiwoo.civet.account.service.local.AccountService;
import com.niiwoo.civet.trade.enums.InvestOrderCloseReasonEnum;
import com.niiwoo.civet.trade.enums.OrderInvestTypeEnum;
import com.niiwoo.civet.trade.service.intelligenceInvest.IntelligenceInvestDubboService;
import com.niiwoo.civet.trade.service.invest.InvestDubboService;
import com.niiwoo.tripod.base.utils.FutureResponses;
import com.niiwoo.tripod.lanmao.component.LanMaoClient;
import com.niiwoo.tripod.lanmao.component.LanMaoDirectService;
import com.niiwoo.tripod.lanmao.enums.LanMaoErrorCodeEnum;
import com.niiwoo.tripod.lanmao.enums.LanMaoGatewayServiceNameEnum;
import com.niiwoo.tripod.lanmao.enums.PreprocessingBusinessTypeEnum;
import com.niiwoo.tripod.lanmao.enums.ResponseCodeEnum;
import com.niiwoo.tripod.lanmao.enums.ResponseStatusEnum;
import com.niiwoo.tripod.lanmao.enums.TradeQueryTypeEnum;
import com.niiwoo.tripod.lanmao.request.CancelPreTransactionRequest;
import com.niiwoo.tripod.lanmao.request.QueryTransactionRequest;
import com.niiwoo.tripod.lanmao.request.UserAutoPreTransactionRequest;
import com.niiwoo.tripod.lanmao.request.UserPreTransactionRequest;
import com.niiwoo.tripod.lanmao.response.LanMaoGatewayDTO;
import com.niiwoo.tripod.lanmao.response.LanMaoResponse;
import com.niiwoo.tripod.lanmao.response.QueryCancelPretransactionResponse;
import com.niiwoo.tripod.lanmao.response.QueryPretransactionResponse;
import com.niiwoo.tripod.lanmao.response.QueryTransactionResponse;
import com.niiwoo.tripod.lanmao.response.UserAutoPreTransactionResponse;
import com.niiwoo.tripod.provider.exception.BizException;

@Service(version = "1.0.0")
public class AccountInvestDubboServiceImpl implements AccountInvestDubboService {
    private static final Logger logger = LoggerFactory.getLogger(AccountInvestDubboServiceImpl.class);

    @Reference(version = "1.0.0")
    private InvestDubboService investDubboService;
    @Reference(version = "1.0.0")
    private IntelligenceInvestDubboService intelligenceInvestDubboService;
    @Autowired
    private AccountInvestService accountInvestService;
    @Autowired
    private LanMaoClient lanMaoClient;
    @Autowired
    private LanMaoDirectService lanMaoDirectService;
    @Autowired
    private AccountService accountService;
   

    @Override
    public LanMaoGatewayDTO buildInvestPayGateWayParam(InvestPayDubboRequestDTO investPayDubboRequestDTO) {
        ProjectInvestCustodyOrder projectInvestCustodyOrder = accountInvestService.generateInvestCustodyOrder(investPayDubboRequestDTO);
        UserPreTransactionRequest request = new UserPreTransactionRequest();
        request.setRequestNo(projectInvestCustodyOrder.getRequestNo());
        request.setPlatformUserNo(projectInvestCustodyOrder.getPlatformUserNo());
        if(Byte.valueOf("1").equals(investPayDubboRequestDTO.getInvestType())) {
        	request.setBizType(PreprocessingBusinessTypeEnum.TENDER);
        }else {
        	request.setBizType(PreprocessingBusinessTypeEnum.CREDIT_ASSIGNMENT);
        	request.setShare(investPayDubboRequestDTO.getShare());
        	request.setCreditsaleRequestNo(investPayDubboRequestDTO.getCreditsaleRequestNo());
        }
        request.setAmount(projectInvestCustodyOrder.getAmount());
        request.setExpired(investPayDubboRequestDTO.getExpired());
        request.setNiiwooRedirectUrl(investPayDubboRequestDTO.getNiiwooRedirectUrl());
        request.setProjectNo(projectInvestCustodyOrder.getProjectNo());
        LanMaoGatewayDTO lanMaoGatewayDTO = lanMaoClient.buildPageParams(LanMaoGatewayServiceNameEnum.USER_PRE_TRANSACTION, request);
        return lanMaoGatewayDTO;
    }

    @Override
    public void accountInvest(InvestPayDubboRequestDTO investPayDubboRequestDTO) {
        ProjectInvestCustodyOrder projectInvestCustodyOrder = accountInvestService.generateInvestCustodyOrder(investPayDubboRequestDTO);
        String requestNo = projectInvestCustodyOrder.getRequestNo();

        UserAutoPreTransactionRequest request = new UserAutoPreTransactionRequest();
        request.setRequestNo(requestNo);
        request.setPlatformUserNo(projectInvestCustodyOrder.getPlatformUserNo());
        if(Byte.valueOf("1").equals(investPayDubboRequestDTO.getInvestType())) {
        	request.setBizType(PreprocessingBusinessTypeEnum.TENDER);
        }else {
        	request.setShare(investPayDubboRequestDTO.getShare());
        	request.setCreditsaleRequestNo(investPayDubboRequestDTO.getCreditsaleRequestNo());
        	request.setBizType(PreprocessingBusinessTypeEnum.CREDIT_ASSIGNMENT);
        }
        
        request.setAmount(projectInvestCustodyOrder.getAmount());
        request.setProjectNo(projectInvestCustodyOrder.getProjectNo());
        logger.info("直连投资请求参数：" + JSON.toJSONString(request));
        CompletableFuture<UserAutoPreTransactionResponse> future = lanMaoDirectService.userAutoPreTransaction(request);
        try {
            UserAutoPreTransactionResponse userAutoPreTransactionResponse = future.get();
            logger.info("直连投资响应参数：" + JSON.toJSONString(userAutoPreTransactionResponse));
            Byte code = userAutoPreTransactionResponse.getCode();
            String status = userAutoPreTransactionResponse.getStatus();
            String errorCode = userAutoPreTransactionResponse.getErrorCode();
            String errorMessage = userAutoPreTransactionResponse.getErrorMessage();
            this.accountInvestExternalHandle(requestNo, code, status, errorCode, errorMessage);
        } catch (Exception e) {
            logger.error("直连投资失败：" + JSON.toJSONString(request), e);
            if (e instanceof BizException) {
                throw (BizException) e;
            } else {
                throw new BizException("ACC10016", "系统繁忙，稍后再试");// 投资授权预处理失败
            }
        }
    }

    @Override
    public void accountInvestInternalHandle(Long investOrderId) {
        Date queryTime = new Date();
        ProjectInvestCustodyOrder projectInvestCustodyOrder = accountInvestService.queryProjectInvestCustodyOrder(investOrderId);
        if (null == projectInvestCustodyOrder) {// 不一定失败
            investDubboService.investCompleteHandle(investOrderId, false, false, queryTime);
            return;
        }
        QueryTransactionRequest request = new QueryTransactionRequest();
        request.setRequestNo(projectInvestCustodyOrder.getRequestNo());
        request.setTransactionType(TradeQueryTypeEnum.FREEZE);
        logger.info("投资结果主动查询请求参数：" + JSON.toJSONString(request));
        CompletableFuture<QueryTransactionResponse> future = lanMaoDirectService.queryTransaction(request);
        try {
            QueryTransactionResponse response = future.get();
            logger.info("投资结果主动查询响应参数：" + JSON.toJSONString(response));
            Byte code = response.getCode();
            String status = response.getStatus();
            if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
                List<QueryTransactionResponse.TransactionDetail> records = response.getRecords();
                if ("FAIL".equals(records.get(0).getStatus())) {
                    accountInvestService.projectInvestCustodyOrderFailHandle(projectInvestCustodyOrder.getRequestNo());
                    investDubboService.investCompleteHandle(investOrderId, false, false, queryTime);
                } else if ("SUCCESS".equals(records.get(0).getStatus())) {
                    accountInvestService.projectInvestCustodyOrderSuccessHandle(projectInvestCustodyOrder.getRequestNo());
                    investDubboService.investCompleteHandle(investOrderId, true);
                }
            } else if ("100007".equals(response.getErrorCode())) {
                accountInvestService.projectInvestCustodyOrderFailHandle(projectInvestCustodyOrder.getRequestNo());
                investDubboService.investCompleteHandle(investOrderId, false, false, queryTime);
            }
        } catch (Exception e) {
            logger.error("投资结果主动查询失败:" + JSON.toJSONString(request), e);
        }
    }

    @Override
    public Long accountInvestExternalHandle(String requestNo, Byte code, String status, String errorCode, String errorMessage) {
        if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
            // 调用存管系统成功，记账，更新投资订单boolean状态
            Long investOrderId = accountInvestService.projectInvestCustodyOrderSuccessHandle(requestNo);
            investDubboService.investCompleteHandle(investOrderId, true);
            return investOrderId;
        } else if (!LanMaoErrorCodeEnum.SYSTEM_ERROR.getCode().equals(errorCode)
                && !LanMaoErrorCodeEnum.REQUEST_NO_REPEAT.getCode().equals(errorCode)) {
            // 调用存管系统失败，取消投资订单
            Long investOrderId = accountInvestService.projectInvestCustodyOrderFailHandle(requestNo);
            investDubboService.investCompleteHandle(investOrderId, false);
            throw new BizException("ACC10016", errorMessage);
        } else {
            throw new BizException("ACC10016", errorMessage);
        }
    }

    @Override
    public List<ProjectInvestCustodyOrderDTO> queryProjectInvestCustodyOrderListByInvestOrderIdSet(
            Set<Long> investOrderIdSet) {
        return accountInvestService.queryProjectInvestCustodyOrderListByInvestOrderIdSet(investOrderIdSet);
    }

    @Override
    public void projectInvestCancel(ProjectInvestCancelOrderDTO projectInvestCancelOrderDTO) {
        ProjectInvestCustodyOrder projectInvestCustodyOrder = accountInvestService.generateInvestCancelCustodyOrder(projectInvestCancelOrderDTO);
        CancelPreTransactionRequest request = new CancelPreTransactionRequest();
        request.setRequestNo(projectInvestCustodyOrder.getRequestNo());
        request.setPreTransactionNo(projectInvestCustodyOrder.getPreTransactionNo());
        request.setAmount(projectInvestCustodyOrder.getAmount());
        logger.info("投资解冻处理请求参数：" + JSON.toJSONString(request));
        CompletableFuture<LanMaoResponse> future = lanMaoDirectService.cancelPreTransaction(request);
        boolean needQuery = false;
        boolean investCancelSuccess = false;
        try {
            LanMaoResponse lanMaoResponse = future.get();
            logger.info("投资解冻处理响应参数：" + JSON.toJSONString(lanMaoResponse));
            Byte code = lanMaoResponse.getCode();
            String status = lanMaoResponse.getStatus();
            if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
                investCancelSuccess = true;
            } else {
                logger.error("投资解冻处理失败：{}", projectInvestCustodyOrder.getRequestNo());
                needQuery = true;
            }
        } catch (Throwable e) {
            logger.error("投资解冻处理失败：{}", projectInvestCustodyOrder.getRequestNo(), e);
            needQuery = true;
        }
        if (needQuery) {
            QueryTransactionRequest queryTransactionRequest = new QueryTransactionRequest();
            queryTransactionRequest.setRequestNo(projectInvestCustodyOrder.getRequestNo());
            queryTransactionRequest.setTransactionType(TradeQueryTypeEnum.CANCEL_PRETRANSACTION);
            queryTransactionRequest.setPlatformUserNo(String.valueOf(projectInvestCancelOrderDTO.getAccountId()));
            logger.info("投资解冻查询请求参数：" + JSON.toJSONString(queryTransactionRequest));
            CompletableFuture<QueryCancelPretransactionResponse> queryCancelPretransactionResponseCompletableFuture = lanMaoDirectService.queryCancelPretransaction(queryTransactionRequest);
            try {
                QueryCancelPretransactionResponse queryCancelPretransactionResponse = queryCancelPretransactionResponseCompletableFuture.get();
                logger.info("投资解冻查询响应参数：" + JSON.toJSONString(queryCancelPretransactionResponse));
                Byte code = queryCancelPretransactionResponse.getCode();
                String status = queryCancelPretransactionResponse.getStatus();
                if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
                    if ("UNFREEZED".equals(queryCancelPretransactionResponse.getRecords().get(0).getStatus())) {
                        investCancelSuccess = true;
                    }
                }
            } catch (Throwable e) {
                logger.error("投资解冻查询失败：{}", projectInvestCustodyOrder.getRequestNo(), e);
            }
        }
        if (investCancelSuccess) {
            logger.info("投资解冻成功：{}", projectInvestCustodyOrder.getRequestNo());
            accountInvestService.investCancelCustodyOrderSuccess(projectInvestCustodyOrder.getId());
            InvestOrderCloseReasonEnum closeReasonEnum = InvestOrderCloseReasonEnum.enumOf(projectInvestCancelOrderDTO.getReason());
            if(OrderInvestTypeEnum.INTELLIGENCE.getType().equals(projectInvestCustodyOrder.getInvestType())) {
            	intelligenceInvestDubboService.investCancelSuccess(projectInvestCustodyOrder.getProjectId(),projectInvestCustodyOrder.getInvestOrderId(), closeReasonEnum);
            }else {
            	investDubboService.investCancelSuccess(projectInvestCustodyOrder.getInvestOrderId(), closeReasonEnum);
            }
            
        }
    }

    @Override
    public CompleteInvestOrderResponseDTO completeInvestOrderIfExist(Long accountId, Long investOrderId) {
        ProjectInvestCustodyOrder order = accountInvestService.queryProjectInvestCustodyOrder(investOrderId);
        CompleteInvestOrderResponseDTO responseDTO = new CompleteInvestOrderResponseDTO();
        if (order == null) {    //账户中心不存在网关投资订单，可断定用户未能跳转到存管网关，存管亦无此订单
            return responseDTO.setOrderExists(false);
        }
        //查询存管投资订单状态
        String requestNo = order.getRequestNo();
        responseDTO.setRequestNo(requestNo);
        Date queryTime = new Date();
        QueryTransactionResponse response = queryLanMaoInvestOrder(requestNo);
        Byte code = response.getCode();
        String status = response.getStatus();
        if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
            responseDTO.setOrderExists(true);
            List<QueryTransactionResponse.TransactionDetail> records = response.getRecords();
            if ("FAIL".equals(records.get(0).getStatus())) {
                accountInvestService.projectInvestCustodyOrderFailHandle(requestNo);
                investDubboService.investCompleteHandle(investOrderId, false, false, queryTime);
                responseDTO.setOrderSucceed(false);
                responseDTO.setFailMessage(response.getErrorMessage());
            } else if ("SUCCESS".equals(records.get(0).getStatus())) {
                accountInvestService.projectInvestCustodyOrderSuccessHandle(requestNo);
                investDubboService.investCompleteHandle(investOrderId, true);
                responseDTO.setOrderSucceed(true);
            }
        } else if ("100007".equals(response.getErrorCode())) {
            return responseDTO.setOrderExists(false);   //查询对象不存在，存管无此订单
        }
        return responseDTO;
    }

    private QueryTransactionResponse queryLanMaoInvestOrder(String requestNo) {
        QueryTransactionRequest request = new QueryTransactionRequest();
        request.setRequestNo(requestNo);
        request.setTransactionType(TradeQueryTypeEnum.FREEZE);
        logger.info("投资结果主动查询请求参数：" + JSON.toJSONString(request));
        CompletableFuture<QueryTransactionResponse> future = lanMaoDirectService.queryTransaction(request);
        QueryTransactionResponse response = FutureResponses.get(future);    //有异常则抛出
        logger.info("投资结果主动查询响应参数：" + JSON.toJSONString(response));
        return response;
    }

    @Override
    public InvestPaymentRedoResponseDTO redoInvestOrderPayment(Long accountId, InvestPayDubboRequestDTO requestDTO) {
        Long investOrderId = requestDTO.getInvestOrderId();
        ProjectInvestCustodyOrder order = accountInvestService.queryProjectInvestCustodyOrder(investOrderId);
        InvestPaymentRedoResponseDTO responseDTO = new InvestPaymentRedoResponseDTO();
        if (order == null) {    //账户中心不存在网关投资订单，重新发起
            orderNotExsists(accountId, requestDTO, responseDTO);
        } else {
            String requestNo = order.getRequestNo();
            Date queryTime = new Date();
            QueryTransactionResponse response = queryLanMaoInvestOrder(requestNo);
            Byte code = response.getCode();
            String status = response.getStatus();
            if (ResponseCodeEnum.SUCCESS.getValue().equals(code) && ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
                responseDTO.setOrderExists(true);
                List<QueryTransactionResponse.TransactionDetail> records = response.getRecords();
                if ("FAIL".equals(records.get(0).getStatus())) {
                    accountInvestService.projectInvestCustodyOrderFailHandle(requestNo);
                    investDubboService.investCompleteHandle(investOrderId, false, false, queryTime);
                    responseDTO.setOrderSucceed(false);
                    responseDTO.setFailMessage(response.getErrorMessage());
                } else if ("SUCCESS".equals(records.get(0).getStatus())) {
                    accountInvestService.projectInvestCustodyOrderSuccessHandle(requestNo);
                    investDubboService.investCompleteHandle(investOrderId, true);
                    responseDTO.setOrderSucceed(true);
                }
            } else if ("100007".equals(response.getErrorCode())) {
                //删除本地订单
                accountInvestService.deleteProjectInvestCustodyOrder(order.getId());
                orderNotExsists(accountId, requestDTO, responseDTO);
            }
        }
        return responseDTO;
    }

    private void orderNotExsists(Long accountId, InvestPayDubboRequestDTO requestDTO, InvestPaymentRedoResponseDTO responseDTO) {
        responseDTO.setOrderExists(false);
        AccountBase account = accountService.loadAccountById(accountId);
        if (Byte.valueOf("1").equals(account.getTender())) {    //免密投资
            accountInvest(requestDTO);
            responseDTO.setGateWayMode(false);
        } else {
            LanMaoGatewayDTO gateWayParam = buildInvestPayGateWayParam(requestDTO);
            responseDTO.setGateWayMode(true);
            responseDTO.setGatewayDTO(gateWayParam);
        }
    }

    /**
     * 智能投用户预处理操作
     */
	@Override
	public void intelligenceInvest(Long packageInvestOrderId) {
		// 返回历史生成数据或者新生成数据(新数据调用账户中心分账)，当存在错误的历史数据时，返回null走错误流程
		List<ProjectInvestCustodyOrder> projectInvestCustodyOrders = accountInvestService.generatePackageInvest(packageInvestOrderId);
		// 如果出现错误的历史订单，走错误流程
		if (CollectionUtils.isEmpty(projectInvestCustodyOrders)) {
			intelligenceCancel(packageInvestOrderId);
			return;
		}
		Byte sucessSatus = Byte.valueOf("1");
		for (ProjectInvestCustodyOrder projectInvestCustodyOrder : projectInvestCustodyOrders) {
			if (sucessSatus.equals(projectInvestCustodyOrder.getStatus())) {
				continue;
			}
			
			//调用存管用户预处理
			boolean isSuccess = invokeCustodyOrder(projectInvestCustodyOrder);
			if (!isSuccess) {
				//出现异常走异常流程
				intelligenceCancel(packageInvestOrderId);
				return;
			}
			//修改订单状态，调用存管是默认订单是成功的
			accountInvestService.intelligenceInvestCustodyOrderSuccess(projectInvestCustodyOrder.getId());
		}
		//账户处理
		accountInvestService.intelligenceInvestSuccess(packageInvestOrderId,projectInvestCustodyOrders);
		//智能投投资成功处理 
		intelligenceInvestDubboService.intelligenceInvestSuccess(packageInvestOrderId);
	}
	/**
	 * 智能投调用存管
	 * @param projectInvestCustodyOrder
	 * @return
	 */
	private boolean invokeCustodyOrder(ProjectInvestCustodyOrder projectInvestCustodyOrder) {
		String requestNo = projectInvestCustodyOrder.getRequestNo();
        UserAutoPreTransactionRequest request = new UserAutoPreTransactionRequest();
        request.setRequestNo(requestNo);
        request.setPlatformUserNo(projectInvestCustodyOrder.getPlatformUserNo());
        request.setBizType(PreprocessingBusinessTypeEnum.TENDER);
        request.setAmount(projectInvestCustodyOrder.getAmount());
        request.setProjectNo(projectInvestCustodyOrder.getProjectNo());
        logger.info("智能投直连投资请求参数：" + JSON.toJSONString(request));
        CompletableFuture<UserAutoPreTransactionResponse> future = lanMaoDirectService.userAutoPreTransaction(request);
        try {
            UserAutoPreTransactionResponse userAutoPreTransactionResponse = future.get();
            logger.info("智能投直连投资响应参数：" + JSON.toJSONString(userAutoPreTransactionResponse));
            Byte code = userAutoPreTransactionResponse.getCode();
            String status = userAutoPreTransactionResponse.getStatus();
            String errorCode = userAutoPreTransactionResponse.getErrorCode();
            String errorMessage = userAutoPreTransactionResponse.getErrorMessage();
            //没有返回正确，当做错误处理
            if (!ResponseCodeEnum.SUCCESS.getValue().equals(code) ||! ResponseStatusEnum.SUCCESS.getValue().equals(status)) {
            	logger.warn("智能投直连投资异常,错误编码{},错误信息{},请求信息{}",errorCode,errorMessage,JSON.toJSONString(userAutoPreTransactionResponse));
            	return false;
            } 
        } catch (Exception e) {
        	logger.warn("智能投直连投资异常,请求信息{},错误信息{}",JSON.toJSONString(request),e.getMessage());
           return false;
        }
		return true;
	}
	/**
	 * 
	 */
	@Override
	public void intelligenceCancel(Long projectPackageOrderId) {
		//先将投资订单状态改为关闭中
		intelligenceInvestDubboService.intelligenceInvestPreCancel(projectPackageOrderId);
		List<ProjectInvestCustodyOrder> projectInvestCustodyOrderss = accountInvestService.generatePackageInvestCancel(projectPackageOrderId);
		if(CollectionUtils.isEmpty(projectInvestCustodyOrderss)) {
			return;
		}
		boolean hasError = false;
		//一条一条的解冻
		for (ProjectInvestCustodyOrder projectInvestCustodyOrder : projectInvestCustodyOrderss) {
			if(Byte.valueOf("1").equals(projectInvestCustodyOrder.getStatus())) {
				continue;
			}
			//调用存管用户预处理,调用成功，进行修改状态，调用失败不处理，等待定时任务继续触发
			boolean isSuccess = invokeCustodyOrderCancel(projectInvestCustodyOrder);
			if(isSuccess) {
				//修改订单状态
				accountInvestService.intelligenceInvestCustodyOrderSuccess(projectInvestCustodyOrder.getId());
			}else {
				hasError = true;
			}
		}
		//如果所有订单都成功接触预处理，进行数据回撤
		if(!hasError) {
			//调用智能投资金解冻
			accountInvestService.intelligenceInvestFalse(projectPackageOrderId);
			intelligenceInvestDubboService.intelligenceCancel(projectPackageOrderId);
		}
		
	}
	/**
	 * 预处理解冻操作(幂等接口，可以多次调用)
	 * @param projectInvestCustodyOrder
	 * @return
	 */
	private boolean invokeCustodyOrderCancel(ProjectInvestCustodyOrder projectInvestCustodyOrder) {
		
		QueryTransactionRequest requestQuery = new QueryTransactionRequest();
		requestQuery.setRequestNo(projectInvestCustodyOrder.getPreTransactionNo());
		requestQuery.setTransactionType(TradeQueryTypeEnum.PRETRANSACTION);
        CompletableFuture<QueryPretransactionResponse> queryResult =lanMaoDirectService.queryPretransaction(requestQuery);
        try {
			QueryPretransactionResponse result=queryResult.get();
			//订单不存在，不需要解冻
			if(LanMaoErrorCodeEnum.QUERY_OBJECT_NOT_EXIST.getCode().equals(result.getErrorCode())) {
				return true;
			}
			//调用成功，判断是否已经解冻,冻结失败，已解冻 都不需要发起解冻请求
			if(ResponseCodeEnum.SUCCESS.getValue().equals(result.getCode())&&ResponseStatusEnum.SUCCESS.getValue().equals(result.getStatus())) {
				String records = result.getRecords().get(0).getStatus();
				if("FAIL".equals(records)||"UNFREEZED".equals(records)) {
					return true;
				}
			}
		} catch (InterruptedException | ExecutionException e1) {
			//异常情况调用解冻，幂等调用不会影响程序
			 logger.warn("智能投查询冻结订单失败，订单编号{}，{}",projectInvestCustodyOrder.getPreTransactionNo(),e1.getMessage());
		}
		
		
		CancelPreTransactionRequest request = new CancelPreTransactionRequest();
        request.setRequestNo(projectInvestCustodyOrder.getRequestNo());
        request.setPreTransactionNo(projectInvestCustodyOrder.getPreTransactionNo());
        request.setAmount(projectInvestCustodyOrder.getAmount());
        logger.info("智能投投资解冻处理请求参数：" + JSON.toJSONString(request));
        CompletableFuture<LanMaoResponse> future = lanMaoDirectService.cancelPreTransaction(request);
        try {
            LanMaoResponse lanMaoResponse = future.get();
            logger.info("智能投投资解冻处理响应参数：" + JSON.toJSONString(lanMaoResponse));
            Byte code = lanMaoResponse.getCode();
            String status = lanMaoResponse.getStatus();
            //幂等接口
            if (ResponseCodeEnum.SUCCESS.getValue().equals(code) ) {
            	if(ResponseStatusEnum.SUCCESS.getValue().equals(status)||
            			LanMaoErrorCodeEnum.QUERY_OBJECT_NOT_EXIST.getCode().equals(lanMaoResponse.getErrorCode())||
            			LanMaoErrorCodeEnum.REQUEST_NO_REPEAT.getCode().equals(lanMaoResponse.getErrorCode())) {
            		logger.info("智能投投资解冻处理成功{}", projectInvestCustodyOrder.getRequestNo());
            		return true;
            	}
            	logger.warn("智能投投资解冻处理失败{}", projectInvestCustodyOrder.getRequestNo());
            	return false;
            } else {
                logger.warn("智能投投资解冻处理失败：{},{}", projectInvestCustodyOrder.getRequestNo(),lanMaoResponse);
                return false;
            }
        } catch (Throwable e) {
            logger.warn("智能投投资解冻处理失败：{}", projectInvestCustodyOrder.getRequestNo(), e);
            return false;
        }
	}
}
